package com.oyjd.ybx.fw.task;

import java.util.List;

/**
 * 多任务控制器
 * 
 * @author 欧建东
 * @email oyjd@163.com
 * 
 */
public class MyTask<T> {
	/**
	 * 并发运行的任务数
	 */
	private int runCount;
	/**
	 * 资源对象
	 */
	private List<T> paras;
	/**
	 * 线程中运行的方法体
	 */
	private MyTaskLogic<T> fun;
	/**
	 * 当前任务数
	 */
	private int p = 0;
	/**
	 * 任务总数
	 */
	private int count;
	/**
	 * 倒数器
	 */
	private int downCount;

	/**
	 * 构造函数
	 * 
	 * @param runCount
	 *            并发运行的任务数
	 * @param sou
	 *            总任务资源
	 * @param listener
	 *            任务实现逻辑
	 */
	public MyTask(int runCount, List<T> paras, MyTaskLogic<T> fun) {
		this.runCount = runCount;
		this.paras = paras;
		this.fun = fun;
		this.downCount = paras.size();
		this.count = paras.size();
	}

	/**
	 * 线程完成事件的公共监听器
	 */
	private InnerRunnableListener listener = new InnerRunnableListener() {

		public void finish() {
			downCount--;
			if (downCount <= 0) {
				fun.finishAll(paras);
			} else {
				doOneTask();
			}
		}
	};

	/**
	 * 启动任务
	 */
	public void start() {
		for (int i = 0; i < runCount; i++) {
			doOneTask();
		}
	}

	/**
	 * 启动一个任务
	 */
	private synchronized void doOneTask() {
		if (p < paras.size()) {
			new Thread(new InnerRunnable<T>(count, p, paras.get(p++), fun, listener)).start();
		}
	}

}

/**
 * 内部任务线程
 * 
 * @author 欧建东
 * @email oyjd@163.com
 * 
 */
class InnerRunnable<T> implements Runnable {
	private int count;// 任务总数
	private int pos;// 任务启动的位置
	private T para;// 当前任务资源
	private MyTaskLogic<T> fun;// 任务方法体
	private InnerRunnableListener listener;

	/**
	 * 构造函数
	 * 
	 * @param count
	 * @param pos
	 * @param para
	 * @param fun
	 * @param listener
	 */
	public InnerRunnable(int count, int pos, T para, MyTaskLogic<T> fun, InnerRunnableListener listener) {
		this.pos = pos;
		this.para = para;
		this.fun = fun;
		this.listener = listener;
	}

	/**
	 * 线程入口
	 */
	public void run() {
		fun.doLogic(count, pos, para);
		listener.finish();
	}

}

/**
 * 内部任务线程完成监听器
 * 
 * @author 欧建东
 * @email oyjd@163.com
 * 
 */
interface InnerRunnableListener {
	void finish();
}
